﻿using DotXxlJob.Core;
using DotXxlJob.Core.Config;
using Mapster;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using XYS.Core.Models;
using XYS.Core.Util.Helper;

namespace XYS.Service.Core
{
    /// <summary>
    /// 缓存服务 相关配置
    /// </summary>
    public static class XXLJobExtension
    {
        /// <summary>
        /// 增加分布式缓存
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public static WebApplicationBuilder AddXXLJob(this WebApplicationBuilder builder, ILogger logger)
        {
            if (!GlobalCoreSetting.EnableXXLJob || !builder.Configuration.AsEnumerable().Any(x => x.Key.ToLower() == "xxljob") || GlobalCoreSetting.NACOS_IP == "localhost") return builder;
            var jobHanderTypes = XYS.Core.Util.Helper.AssemblyHelper.GetAssemblyTypes()
                .Where(x => typeof(IJobHandler).IsAssignableFrom(x)
                && x.IsClass && x.CustomAttributes.Any(a => a.AttributeType == typeof(DotXxlJob.Core.JobHandlerAttribute)))
                .ToList();
            if (jobHanderTypes.Count == 0) return builder;

            if (!int.TryParse(GlobalCoreSetting.NACOS_PORT, out var port)) port = 0;

            //获取自定义日志的接口的所有实现
            var jobLoggerTypes = AssemblyHelper.GetAssemblyTypes()
                .Where(x => x.IsClass && typeof(Service.XXLJobServices.IJobLogger).IsAssignableFrom(x))
                .FirstOrDefault();
            if (jobLoggerTypes != null)
                builder.Services.AddSingleton(typeof(IJobLogger), jobLoggerTypes);

            //获取 xxl-job 配置
            var xxlSetting = builder.Configuration.GetSection("xxljob").Get<XxlJobExecutorOptions>();
            xxlSetting.AppName = $"{GlobalCoreSetting.ServiceName}-executor-dotnet";
            xxlSetting.SpecialBindAddress = GlobalCoreSetting.NACOS_IP;
            xxlSetting.Port = port;
            xxlSetting.LogPath = AppContext.BaseDirectory + "logs";

            //覆盖配置
            builder.Services.AddXxlJobExecutor(configAction => xxlSetting.Adapt(configAction));

            logger.Log(LogLevel.Information, $"注册 xxl-job [{xxlSetting.AppName}]");

            //注册 jobHander
            foreach (var jobHanderType in jobHanderTypes)
            {
                logger.Log(LogLevel.Information, $"jobHander[{jobHanderType.FullName}]");
                builder.Services.AddSingleton(typeof(IJobHandler), jobHanderType);
            }

            //自动注册  执行器
            builder.Services.AddAutoRegistry();

            return builder;
        }

    }
}
